﻿using IQReportes.Models;
using IQReportes.Utils;
using IQReportes.ViewModels;
using IQReportes.Boundary;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using IQReportes.Models.Logica;
using System.IO;


namespace IQReportes.Controllers
{
    /// <summary>
    /// Controller para la vista de transaccionse
    /// </summary>
    public class TransaccionesController : Controller
    {
        /// <summary>
        /// lógica de transacción
        /// </summary>
        LogicaTransaccion logicaTransaccion = new LogicaTransaccion();
        /// <summary>
        /// lógica de usuarios
        /// </summary>
        LogicaUsuario logicaUsuario = new LogicaUsuario();
        /// <summary>
        /// formatter de datos para la vista
        /// </summary>
        FormatterTransacciones formateador = new FormatterTransacciones();
        /// <summary>
        /// lógica perfil
        /// </summary>
        LogicaPerfil logicaPerfil = new LogicaPerfil();
        /// <summary>
        /// index de transacciones
        /// </summary>
        /// <returns>vista principal de transacciones</returns>
        public ActionResult Index()
        {

            //logicaTransaccion.obtenerConsolidadoEstados(null,null,3,1,1,"Lima","Lima");    

            if (!UsuarioController.usuarioConectado())
            {
                return (new UsuarioController()).Logout();
            }
            else
            {
                return View("Index", logicaUsuario.getUsuarioActualConf());
            }
            //logicaTransaccion.obtenerConsolidadoEstados(null,null,3,1,1,"Lima","Lima");    

        }
        /// <summary>
        /// obtener datos del módulo a partir de la petición realizada
        /// </summary>
        /// <param name="fechaInicial">fecha inicial</param>
        /// <param name="fechaFinal">fecha final</param>
        /// <param name="modulo">número de módulo</param>
        /// <param name="tipoValorTree">valor del tree</param>
        /// <param name="tipoChart">tipo de chart</param>
        /// <param name="institucion">institución seleccionada</param>
        /// <param name="puntoEquilibrio"></param>
        /// <param name="nivelTreeHijo">nivel del nodo hijo del tree</param>
        /// <param name="nivelTreePadre">nivel del nodo padre del tree</param>
        /// <param name="nivelTree">nivel actual del tree</param>
        /// <param name="codHijo">código del nodo hijo del tree</param>
        /// <param name="codPadre">código del nodo padre del tree</param>
        /// <param name="tipoTxNivel1">tipo de transacción seleccionado para nivel 1</param>
        /// <param name="tipoTxNivel2">tipo de transacción selccionada para nivel 2</param>
        /// <param name="estadoTx">estado de transacción seleccionada</param>
        /// <param name="transaccionesBotonFechaSeleccion">selección de botón de rango de fecha</param>
        /// <returns>datos del módulo requerido</returns>
        public ActionResult getData(string fechaInicial, string fechaFinal, int modulo, int? tipoValorTree,
                int tipoChart,int institucion,int? puntoEquilibrio, string nivelTreeHijo,string nivelTreePadre,int nivelTree,
                string codHijo,string codPadre,
                string tipoTxNivel1, string tipoTxNivel2, string estadoTx,int transaccionesBotonFechaSeleccion)
        {
            //string aux = fechaInicial + "|" + fechaFinal + "|" + modulo + "|" + tipoValorTree + "|" + tipoChart + "|" + institucion + "|" + puntoEquilibrio;
            QueryTXModel query = new QueryTXModel(fechaInicial,fechaFinal,modulo,tipoValorTree,tipoChart,institucion,
                                                    puntoEquilibrio,nivelTreeHijo,nivelTreePadre,codHijo,codPadre,
                                                    nivelTree,tipoTxNivel1,tipoTxNivel2,estadoTx,transaccionesBotonFechaSeleccion);
            ChartViewData dataVista = new ChartViewData();
            string cantidad = "";
            List<String[]> datos = null;
            if (!UsuarioController.usuarioConectado())
            {
                (new UsuarioController()).Logout();
            }
            string error = logicaPerfil.tienePermisoVerTx(modulo);
            if (error.Length > 0)
            {
                dataVista.error = error;
            }
            else
            {
                
                if (modulo == Constantes.MODULO1TREE)
                {
                List<TreeTransaccion> consolidado;
                //return Json(getDataTree(query), JsonRequestBehavior.AllowGet);
                      consolidado = logicaTransaccion.obtenerConsolidadoTransacciones(query.antiguedad,query.codTablaTiempo,
                                                                                    query.institucion,query.tipoValorTree,
                                                                                    query.antiguedadHasta);
                datos = FormatterTransacciones.consTreeToChartView(consolidado, query.tipoValorTree);
            }
                else if (modulo == Constantes.MODULO2TIPOTX)
                {
                    
                List<ConsolidadoTipoTransaccion> consolidado;
                consolidado = logicaTransaccion.obtenerConsolidadoTipos(query.idEstadoTx,query.idCategoriaTx,query.nivelTree,query.antiguedad,
                    query.codTablaTiempo, query.codHijo, query.codPadre, query.tipoChart, query.institucion,query.antiguedadHasta);
                cantidad = logicaTransaccion.obtenerCantTxnsConsolidadoTipos(consolidado);
                    
                datos = FormatterTransacciones.consTipoToChartView(consolidado, tipoChart, query.cantidadDeDias,query.idEstadoTx);
                //datos = getDataModulo(query);
                //return Json(getDataModulo(query), JsonRequestBehavior.AllowGet);
            }
                else if (modulo == Constantes.MODULO3ESTADOTX)
                {
                
                List<ConsolidadoEstadoTransaccion> consolidado;
                consolidado = logicaTransaccion.obtenerConsolidadoEstados(query.idTipoTx, query.idCategoriaTx, query.nivelTree,
                    query.antiguedad, query.codTablaTiempo, query.codHijo, query.codPadre, query.tipoChart, query.institucion,query.antiguedadHasta);
                cantidad = logicaTransaccion.obtenerCantTxnsConsolidadoEstados(consolidado);
                datos = FormatterTransacciones.consEstadoToChartView(consolidado, tipoChart, query.cantidadDeDias);

                //datos = getDataModulo(query);
                //return Json(getDataModulo(query), JsonRequestBehavior.AllowGet);
            }
                else if (modulo == Constantes.MODULO4MONTOTX)
                {
                cantidad = "" + 400;
                List<ConsolidadoMontoTransaccion> consolidado;
                consolidado = logicaTransaccion.obtenerConsolidadoMontos(query.idEstadoTx, query.idCategoriaTx, query.idTipoTx,
                    query.codHijo, query.codPadre, query.nivelTree, query.codTablaTiempo, query.antiguedad,query.tipoChart,query.institucion,
                    query.antiguedadHasta);
                datos = FormatterTransacciones.consMontoToChartView(consolidado, tipoChart, query.nivelTree,query.cantidadDeDias);
                //return Json(getDataModulo(query), JsonRequestBehavior.AllowGet);
            }
            /*
                cantidad = "100";
                if (modulo == Constantes.MODULO1TREE)
                {
                    datos = getDataTree(query);
                }
                else datos = getDataModulo(query);*/
            }
            

           // datos = Formatter.consolidadoToChartView(consolidado,tipoChart);
            
            //datos = getDataModulo(query);

            /* //PARA PRUEBAS CON DATOS HARDCODE
            ChartViewData dataVista = new ChartViewData();
            string cantidad = "100";
            List<String[]> datos = null;
            if (modulo == Constantes.MODULO1TREE)
            {
                datos = getDataTree(query);
            }
            else datos = getDataModulo(query);*/

            dataVista.cantidadTotal = cantidad;
            dataVista.datos = datos;
            return Json(dataVista, JsonRequestBehavior.AllowGet);
        }
        /// <summary>
        /// convertir vista a string
        /// </summary>
        /// <param name="viewName">nombre de la vista</param>
        /// <param name="model">datos para enviar a la vista</param>
        /// <returns>string con la vista generada con el model recibido</returns>
        protected string RenderPartialViewToString(string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = ControllerContext.RouteData.GetRequiredString("action");

            ViewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
                ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);
                return sw.GetStringBuilder().ToString();
            }
        }
        /// <summary>
        /// descargar los datos del módulo a partir de la petición realizada
        /// </summary>
        /// <param name="fechaInicial">fecha inicial</param>
        /// <param name="fechaFinal">fecha final</param>
        /// <param name="modulo">número de módulo</param>
        /// <param name="tipoValorTree">valor del tree</param>
        /// <param name="tipoChart">tipo de chart</param>
        /// <param name="institucion">institución seleccionada</param>
        /// <param name="puntoEquilibrio"></param>
        /// <param name="nivelTreeHijo">nivel del nodo hijo del tree</param>
        /// <param name="nivelTreePadre">nivel del nodo padre del tree</param>
        /// <param name="nivelTree">nivel actual del tree</param>
        /// <param name="codHijo">código del nodo hijo del tree</param>
        /// <param name="codPadre">código del nodo padre del tree</param>
        /// <param name="tipoTxNivel1">tipo de transacción seleccionado para nivel 1</param>
        /// <param name="tipoTxNivel2">tipo de transacción selccionada para nivel 2</param>
        /// <param name="estadoTx">estado de transacción seleccionada</param>
        /// <param name="transaccionesBotonFechaSeleccion">selección de botón de rango de fecha</param>
        /// <returns>archivo excel con los datos del módulo requerido</returns>
        public ActionResult Download(string fechaInicial, string fechaFinal, int modulo, int? tipoValorTree,
                int tipoChart, int institucion, int? puntoEquilibrio, string nivelTreeHijo, string nivelTreePadre, int nivelTree,
                string codHijo, string codPadre,
                string tipoTxNivel1, string tipoTxNivel2, string estadoTx, int transaccionesBotonFechaSeleccion)
        {
            QueryTXModel query = new QueryTXModel(fechaInicial, fechaFinal, modulo, tipoValorTree, tipoChart, institucion,
                                                    puntoEquilibrio, nivelTreeHijo, nivelTreePadre, codHijo, codPadre,
                                                    nivelTree, tipoTxNivel1, tipoTxNivel2, estadoTx, transaccionesBotonFechaSeleccion);
            string cantidad;
            List<String[]> datos = new List<string[]>();
            if (modulo == Constantes.MODULO1TREE)
            {
                List<TreeTransaccion> consolidado;
                //return Json(getDataTree(query), JsonRequestBehavior.AllowGet);
                consolidado = logicaTransaccion.obtenerConsolidadoTransacciones(query.antiguedad, query.codTablaTiempo,
                                                                                query.institucion, query.tipoValorTree, 
                                                                                query.antiguedadHasta);
                datos = FormatterTransacciones.consTreeToChartView(consolidado, query.tipoValorTree);
            }
            else if (modulo == Constantes.MODULO2TIPOTX)
            {

                List<ConsolidadoTipoTransaccion> consolidado;
                consolidado = logicaTransaccion.obtenerConsolidadoTipos(query.idEstadoTx, query.idCategoriaTx, query.nivelTree, query.antiguedad,
                    query.codTablaTiempo, query.codHijo, query.codPadre, query.tipoChart, query.institucion,query.antiguedadHasta);
                cantidad = logicaTransaccion.obtenerCantTxnsConsolidadoTipos(consolidado);

                datos = FormatterTransacciones.consTipoToChartView(consolidado, tipoChart, query.cantidadDeDias, query.idEstadoTx);
                //datos = getDataModulo(query);
                //return Json(getDataModulo(query), JsonRequestBehavior.AllowGet);
            }
            else if (modulo == Constantes.MODULO3ESTADOTX)
            {

                List<ConsolidadoEstadoTransaccion> consolidado;
                consolidado = logicaTransaccion.obtenerConsolidadoEstados(query.idTipoTx, query.idCategoriaTx, query.nivelTree,
                    query.antiguedad, query.codTablaTiempo, query.codHijo, query.codPadre, query.tipoChart, query.institucion,
                    query.antiguedadHasta);
                cantidad = logicaTransaccion.obtenerCantTxnsConsolidadoEstados(consolidado);
                datos = FormatterTransacciones.consEstadoToChartView(consolidado, tipoChart, query.cantidadDeDias);

                //datos = getDataModulo(query);
                //return Json(getDataModulo(query), JsonRequestBehavior.AllowGet);
            }
            else if (modulo == Constantes.MODULO4MONTOTX)
            {
                cantidad = "" + 400;
                List<ConsolidadoMontoTransaccion> consolidado;
                consolidado = logicaTransaccion.obtenerConsolidadoMontos(query.idEstadoTx, query.idCategoriaTx, query.idTipoTx,
                    query.codHijo, query.codPadre, query.nivelTree, query.codTablaTiempo, query.antiguedad, query.tipoChart, query.institucion
                    ,query.antiguedadHasta);
                datos = FormatterTransacciones.consMontoToChartView(consolidado, tipoChart, query.nivelTree, query.cantidadDeDias);
                //return Json(getDataModulo(query), JsonRequestBehavior.AllowGet);
            }

            
            //datos.Add(new String[] { "H1", "H2" });
            //datos.Add(new String[] { "D1", "D2" });
            //datos.Add(new String[] { "d1", "d2" });
            //datos.Add(new String[] { "f1", "f2" });
            string html = RenderPartialViewToString("PartialViewName", datos);
            // if your view don't have any model then you can pass as null

            html = html.Replace("\n", "");
            html = html.Replace("\r", "");
            html = html.Replace("  ", "");

            return new DownloadFileActionResult(html, "Descarga.xls");
        }

    #region DataPrueba
        private List<String[]> getDataPie(string ff)
        {
            List<String[]> aux = new List<String[]>();
            aux.Add(new String[] { "string", "number" });//tipo cabeceras
            aux.Add(new String[] { "Topping","Slices" });//nombre cabeceras
            aux.Add(new String[] { ff, "3" });
            aux.Add(new String[] { "Depósitos", "7" });
            aux.Add(new String[] { "Recargas ñ", "3" });
            aux.Add(new String[] { "Pagos", "4" });
            aux.Add(new String[] { "Retiros", "2" });
            return aux;
        }


        private List<String[]> getDataColumn(string ff)
        {
            List<String[]> aux = new List<String[]>();
            aux.Add(new String[] { "string", "number", "number", "number", "number"});//tipo cabeceras
            aux.Add(new String[] { "Year", "Aprobada", "Trunca", "Por imprimir", "Exitosa"});//nombre cabeceras
            aux.Add(new String[] { "24/07/2013", "1336060", "3817614", "974066", "21104797"});
            
            return aux;
        }
        private List<String[]> getDataLine(string ff)
        {
            List<String[]> aux = new List<String[]>();
            aux.Add(new String[] { "string", "number", "number", "number","number" });//tipo cabeceras
            aux.Add(new String[] { "X","Aprobada" , "Trunca", "Por imprimir","Exitosa" });//nombre cabeceras
            aux.Add(new String[] { "10/07/2013", "123", "12", "50","30" });
            aux.Add(new String[] { "17/07/2013", "10", "100", "50","20" });
            aux.Add(new String[] { "24/07/2013", "30", "1", "1000","10" });
            return aux;
        }
        private List<String[]> getDataTable(string ff)
        {
            List<String[]> aux = new List<String[]>();
            aux.Add(new String[] { "string", "number", "number", "number", "number" });//tipo cabeceras
            aux.Add(new String[] { "tablaCol1", "#TX", "Cargos", "Abonos", "Total" });//nombre cabeceras
            aux.Add(new String[] { "24/07/2013", "40", "400", "200", "200" });
            for (int i = 0; i < 20; i++)
            {
                aux.Add(new String[] { "24/07/2013", "40", "400", "200", "200" });
            }
            return aux;
        }
        private List<String[]> getDataTableDir()
        {
            List<String[]> aux = new List<String[]>();
            aux.Add(new String[] { "string", "number", "number","number","number"});//tipo cabeceras
            aux.Add(new String[] { "DIR", "#TX", "Cargos", "Abonos","Total" });//nombre cabeceras
            aux.Add(new String[] { "DIR10101", "30", "400", "200", "200" });
            aux.Add(new String[] { "DIR20202", "40", "500", "100", "400" });
            aux.Add(new String[] { "DIR30303", "50", "400", "200", "200" });
            return aux;
        }


        private List<String[]> getDataModulo(QueryTXModel query)
        {
            //return getDataPie(query.tipoChart + "");
            var aux = query.tipoChart + "";
            if (query.tipoChart == Constantes.PIECHART)
                return getDataPie(aux + query.fechaInicial+"|"+query.fechaFinal+"|"+query.nivelTreeHijo+"|"+query.nivelTreePadre+"|"+query.tipoTxNivel1 + "|"+
                    query.tipoTxNivel2 + "|" + query.estadoTx);
            if (query.tipoChart == Constantes.COLUMNCHART)
                return getDataColumn(aux); 
            if (query.tipoChart == Constantes.LINECHART)
                return getDataLine(aux);
            if (query.nivelTreeHijo.CompareTo("Local 1") == 0 || query.nivelTreeHijo.CompareTo("Local 2") == 0 || query.nivelTreeHijo.Substring(0,3).CompareTo("DIR")==0)
                return getDataTableDir();
            return getDataTable(aux);
        }

        private List<String[]> getDataModulo2(QueryTXModel query)
        {   
            return getDataPie(query.tipoChart+"");
        }

        private List<String[]> getDataModulo3(QueryTXModel query)
        {
            //return getDataPie(query.tipoChart + "");
            var aux = query.tipoChart + "";
            if (query.tipoChart == Constantes.PIECHART)
                return getDataPie(aux);
            else if (query.tipoChart == Constantes.COLUMNCHART)
                return getDataColumn(aux);
            else if (query.tipoChart == Constantes.LINECHART)
                return getDataLine(aux);
            return getDataTable(aux);
        }

        private List<String[]> getDataModulo4(QueryTXModel query)
        {
            return null;
        }

        public List<String[]> getDataTree(QueryTXModel query)
        {
            string parametro = "Perú ";
            List<String[]> aux = new List<String[]>();

            aux.Add(new String[] { "string", "string", "number", "number", "string", "string" });
            aux.Add(new String[] { "Location", "Parent", "Market trade volume (size)", "Market increase/decrease (color)", "codHijo", "codPadre" });
            aux.Add(new String[] { "Lima", parametro, "0", "0", "hijo1", "cod1" });
            aux.Add(new String[] { "Anchash", parametro, "0", "0", "hijo2", "cod1" });
            aux.Add(new String[] { "Arequipa", parametro, "0", "0", "hijo3", "cod1" });
            aux.Add(new String[] { "Ica", parametro, "0", "0", "hijo4", "cod1" });
            aux.Add(new String[] { "Puno", parametro, "0", "0", "hijo5", "cod1" });
            aux.Add(new String[] { "Prov 1", "Lima", "11", "10", "codgg-1", "hijo1" });
            int max = 127;

            for (int i = 0; i < max; i++)
            {
                aux.Add(new String[] { "Prov " + (i + 2), "Lima", "0", "0", "codgg" + i, "hijo1" });
                for (int j = 0; j < 10; j++)
                {
                    aux.Add(new String[] {"Dis"+i+j ,"Prov " + (i + 2), "0", "0","codff"+j , "codgg" + i });
                    for (int z = 0; z < 10; z++)
                    {
                        aux.Add(new String[] { "Local" + z+i+j, "Dis" +i+j, "52", "31", "codhh" + z ,"codff" + j});
                    }
                }
            }
            aux.Add(new String[] { parametro, null, "0", "0", "cod1", null });

            return aux;
            
        }
    #endregion
    }
}
